#include "BSP_Uart.h"

/*串口1 */
Uart_TypeDef gst_Uart1 = 
{
    .pst_huart  = &huart1,
    .pst_DEPort = NULL
};


/*串口2*/
Uart_TypeDef gst_Uart2 = 
{
    .pst_huart  = &huart2,
    .pst_DEPort = USART2_EN_GPIO_Port,
    .ul_DEPin   = USART2_EN_Pin
};
/*串口3 */
Uart_TypeDef gst_Uart3 = 
{
    .pst_huart  = &huart3,
    .pst_DEPort = NULL
};


/*串口4 */
Uart_TypeDef gst_Uart4 = 
{
    .pst_huart  = &huart4,
    .pst_DEPort = NULL
};

/*串口5 */
Uart_TypeDef gst_Uart5 = 
{
    .pst_huart  = &huart5,
    .pst_DEPort = NULL
};
/*串口6 */
Uart_TypeDef gst_Uart6 = 
{
    .pst_huart  = &huart6,
    .pst_DEPort = USART6_EN_GPIO_Port,
    .ul_DEPin   = USART6_EN_Pin
};


/**
 * 函数功能：串口发送
 * 参    数：pst_UartStruct 串口结构体指针
 *           puch_Data 发送数据缓存
 *           uin_Size 发送字节
 * 返 回 值：true 成功，false 失败
 */
uint8_t STM32UartTransmit(Uart_TypeDef *pst_UartStruct, uint8_t *puch_Data, uint16_t uin_Size)
{
    /*参数检查*/
    if((pst_UartStruct == NULL) || (puch_Data == NULL))
    {
        return false;
    }

    if(uin_Size == 0)
    {
        return true;
    }
		

    /*作为RS485的串口切换到发送模式*/
    if(pst_UartStruct->pst_DEPort != NULL)
    {
        HAL_GPIO_WritePin(pst_UartStruct->pst_DEPort, pst_UartStruct->ul_DEPin, GPIO_PIN_SET);
    }
		
		//printf("STM32UartTransmit uin_size is %d",uin_Size);
    if(HAL_UART_Transmit_DMA(pst_UartStruct->pst_huart, puch_Data, uin_Size) != HAL_OK)
    {
        /*发送失败时作为RS485的串口切换到接收*/
        if(pst_UartStruct->pst_DEPort != NULL)
        {
            HAL_GPIO_WritePin(pst_UartStruct->pst_DEPort, pst_UartStruct->ul_DEPin, GPIO_PIN_RESET);
        }

        return false;
    }

    return true;
}

/**
 * 函数功能：串口开启接收
 * 参    数：pst_UartStruct 串口结构体指针
 *           puch_Data 接收数据缓存
 *           uin_MaxSize 接收最大字节数
 * 返 回 值：true 成功，false 失败
 */
uint8_t STM32UartReceive(Uart_TypeDef *pst_UartStruct, uint8_t *puch_Data, uint16_t uin_MaxSize)
{
    /*参数检查*/
    if((pst_UartStruct == NULL) || (puch_Data == NULL))
    {
        return false;
    }

    if(uin_MaxSize == 0)
    {
        return true;
    }

    /*作为RS485的串口切换到接收模式*/
    if (pst_UartStruct->pst_DEPort != NULL)
    {
				//printf("STM32UartReceive ul_DEPin gpio reset-----\n");
        HAL_GPIO_WritePin(pst_UartStruct->pst_DEPort, pst_UartStruct->ul_DEPin, GPIO_PIN_RESET);
    }
    // 保证串口接收功能打开
    while (HAL_UARTEx_ReceiveToIdle_DMA(pst_UartStruct->pst_huart, puch_Data, uin_MaxSize) != HAL_OK)
    {
        printf("HAL_UARTEx_ReceiveToIdle_DMA failed, retrying...\n");
        pst_UartStruct->pst_huart->RxState = HAL_UART_STATE_READY;
        __HAL_UNLOCK(pst_UartStruct->pst_huart);
    }
		//printf("HAL_UARTEx_ReceiveToIdle_DMA success!!!\n");
    return true;
}

/**
 * 函数功能：设置串口波特率
 * 参    数：pst_UartStruct 串口结构体指针
 *           ul_BaudRate 波特率
 * 返 回 值：true 成功，false 失败
 * 备    注: 
 * 
 */
uint8_t STM32UartBaudRate(Uart_TypeDef *pst_UartStruct, uint32_t ul_BaudRate)
{
    /*参数检查*/
    if((pst_UartStruct == NULL) || (IS_UART_BAUDRATE(ul_BaudRate) == false))
    {
        return false;
    }
		
		/* 确保 UART 处于空闲状态 */
    if (pst_UartStruct->pst_huart->gState != HAL_UART_STATE_READY ||
        pst_UartStruct->pst_huart->RxState != HAL_UART_STATE_READY)
    {
        HAL_UART_Abort(pst_UartStruct->pst_huart);
    }

    /*设置波特率，参考UART_SetConfig()库函数*/
    uint32_t pclk;

    pst_UartStruct->pst_huart->Init.BaudRate = ul_BaudRate;


    if(pst_UartStruct->pst_huart->Instance == USART1)
    {
      pclk = HAL_RCC_GetPCLK2Freq();
    }
    else
    {
      pclk = HAL_RCC_GetPCLK1Freq();
    }

#if defined(USART_CR1_OVER8)
    if (pst_UartStruct->pst_huart->Init.OverSampling == UART_OVERSAMPLING_8)
    {
        pst_UartStruct->pst_huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, pst_UartStruct->pst_huart->Init.BaudRate);
    }
    else
    {
        pst_UartStruct->pst_huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, pst_UartStruct->pst_huart->Init.BaudRate);
    }
#else
    pst_UartStruct->pst_huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, pst_UartStruct->pst_huart->Init.BaudRate);
#endif /* USART_CR1_OVER8 */

    return true;
}

/**
 * 函数功能：设置串口数据格式-将上述更改波特率方法改造
 * 参    数：pst_UartStruct 串口结构体指针
 *           BaudRate 波特率
 *           DataBits 数据位
 *           StopBits 停止位
 *           Parity   校验位
 * 返 回 值：true 成功，false 失败
 * 备    注: 
 * 
 */
uint8_t STM32UartSetConfig(Uart_TypeDef *pst_UartStruct)
{
    if (pst_UartStruct == NULL)
        return false;

    UART_HandleTypeDef *huart = pst_UartStruct->pst_huart;

    /* 确保 UART 空闲 */
    if (huart->gState != HAL_UART_STATE_READY || huart->RxState != HAL_UART_STATE_READY)
    {
        HAL_UART_Abort(huart);
    }

    /* 设置参数 */
    huart->Init.BaudRate   = pst_UartStruct->config.BaudRate;
    huart->Init.WordLength = GetWordLengthValue(pst_UartStruct ->config.DataBits);
    huart->Init.StopBits   = GetStopBitsValue(pst_UartStruct->config.StopBits);
    huart->Init.Parity     = GetParityValue(pst_UartStruct->config.Parity);

    // 其他保持默认（如模式）
//    huart->Init.Mode       = UART_MODE_TX_RX;
//    huart->Init.HwFlowCtl  = UART_HWCONTROL_NONE;
//    huart->Init.OverSampling = UART_OVERSAMPLING_16;

    /* 计算并设置 BRR */
    uint32_t pclk = (huart->Instance == USART1||huart->Instance == USART6) ? HAL_RCC_GetPCLK2Freq() : HAL_RCC_GetPCLK1Freq();

#if defined(USART_CR1_OVER8)
    if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
        huart->Instance->BRR = UART_BRR_SAMPLING8(pclk, huart->Init.BaudRate);
    else
        huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
#else
    huart->Instance->BRR = UART_BRR_SAMPLING16(pclk, huart->Init.BaudRate);
#endif

    return true;
}

/**
 * 函数功能：串口发送完成回调函数
 * 参    数：huart 串口结构体指针
 * 返 回 值：无
 */
//static volatile int  g_tx_cplt =0;
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
    if(huart == gst_Uart1.pst_huart)
    {
        if(gst_Uart1.TxCplCallback != NULL)
        {
            gst_Uart1.TxCplCallback(&gst_Uart1);
        }
    }

    else if(huart == gst_Uart2.pst_huart)
    {
        if(gst_Uart2.TxCplCallback != NULL)
        {   
					  //gst_Uart2.IsTxBusy = false;
            gst_Uart2.TxCplCallback(&gst_Uart2);
        }
    }
		else if(huart == gst_Uart3.pst_huart)
    {
        if(gst_Uart3.TxCplCallback != NULL)
        {
            gst_Uart3.TxCplCallback(&gst_Uart3);
        }
    }
    else if(huart == gst_Uart4.pst_huart)
    {
        if(gst_Uart4.TxCplCallback != NULL)
        {
            gst_Uart4.TxCplCallback(&gst_Uart4);
        }
    }
		else if(huart == gst_Uart5.pst_huart)
    {
        if(gst_Uart5.TxCplCallback != NULL)
        {
            gst_Uart5.TxCplCallback(&gst_Uart5);
        }
    }
		else if(huart == gst_Uart6.pst_huart)
    {
        if(gst_Uart6.TxCplCallback != NULL)
        {
            gst_Uart6.TxCplCallback(&gst_Uart6);
        }
    }
}

//阻塞，等待发送完成
//void Wait_Tx_Complete(void)
//{
//	while (g_tx_cplt == 0);
//	g_tx_cplt = 0;
//}

/**
 * 函数功能：串口接收完成回调函数
 * 参    数：huart 串口结构体指针
 *           Size 接收字节数
 * 返 回 值：无
 */
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
    if(huart == gst_Uart1.pst_huart)
    {
        if(gst_Uart1.RxCplCallback != NULL)
        {
            gst_Uart1.RxCplCallback(&gst_Uart1, Size);
        }
    }

    else if(huart == gst_Uart2.pst_huart)
    {
        if(gst_Uart2.RxCplCallback != NULL)
        {
            gst_Uart2.RxCplCallback(&gst_Uart2, Size);
        }
    }
		else if(huart == gst_Uart3.pst_huart)
    {
        if(gst_Uart3.RxCplCallback != NULL)
        {
            gst_Uart3.RxCplCallback(&gst_Uart3, Size);
        }
    }
    else if(huart == gst_Uart4.pst_huart)
    {
        if(gst_Uart4.RxCplCallback != NULL)
        {
            gst_Uart4.RxCplCallback(&gst_Uart4, Size);
        }
    }
		else if(huart == gst_Uart5.pst_huart)
    {
        if(gst_Uart5.RxCplCallback != NULL)
        {
            gst_Uart5.RxCplCallback(&gst_Uart5, Size);
        }
    }
		else if(huart == gst_Uart6.pst_huart)
    {
        if(gst_Uart6.RxCplCallback != NULL)
        {
            gst_Uart6.RxCplCallback(&gst_Uart6, Size);
        }
    }
}




/**
 * 函数功能：串口错误回调函数
 * 参    数：huart 串口结构体指针
 * 返 回 值：无
 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
    if(huart == gst_Uart1.pst_huart)
    {
        if(gst_Uart1.ErrorCallback != NULL)
        {
            gst_Uart1.ErrorCallback(&gst_Uart1);
        }
    }

    else if(huart == gst_Uart2.pst_huart)
    {
        if(gst_Uart2.ErrorCallback != NULL)
        {
            gst_Uart2.ErrorCallback(&gst_Uart2);
        }
    }
		else if(huart == gst_Uart3.pst_huart)
    {
        if(gst_Uart3.ErrorCallback != NULL)
        {
            gst_Uart3.ErrorCallback(&gst_Uart3);
        }
    }
    else if(huart == gst_Uart4.pst_huart)
    {
        if(gst_Uart4.ErrorCallback != NULL)
        {
            gst_Uart4.ErrorCallback(&gst_Uart4);
        }
    }
	  else if(huart == gst_Uart5.pst_huart)
    {
        if(gst_Uart5.ErrorCallback != NULL)
        {
            gst_Uart5.ErrorCallback(&gst_Uart5);
        }
    }
		else if(huart == gst_Uart6.pst_huart)
    {
        if(gst_Uart6.ErrorCallback != NULL)
        {
            gst_Uart6.ErrorCallback(&gst_Uart6);
        }
    }
}

int fputc(int ch, FILE *f)
{
    while(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_TXE) == RESET); 
    HAL_UART_Transmit(&huart1, (uint8_t*)&ch, 1, 0xFFFF);    
	  return ch;    
}


